
#ifdef INT
#  define TYP INTEGER
#else
#ifdef FLOAT
#  define TYP REAL
#else
 #error "Need to give MACRO definition for element type : -DINT or -DFLOAT"
#endif
#endif


PROGRAM PROG_PRINC
!
!compilation : gfortran prog_princ.f90 -fbounds-check
!
IMPLICIT NONE
!DECLARATION DES PARAMETRES


	! LA TAILLE DES MATRICES EST ENTREE EN LIGNE DE COMMANDE LORS DE L' EXECUTION
	INTEGER :: p

	INTEGER :: DIM1
	INTEGER :: DIM2
	INTEGER :: F_COMPTEUR
	INTEGER :: I,J
	CHARACTER*15 :: FORME

	REAL :: INTERMEDIAIRE
	INTEGER :: VALEURMAX,VALEURMIN

	INTEGER :: order
	CHARACTER(len=32) :: arg
	
	!********************POUR LA MATRICE PLEINE 
	TYP,DIMENSION(:),ALLOCATABLE :: U	
	TYP, DIMENSION (:), ALLOCATABLE :: A
	INTEGER :: IERR

	TYP,DIMENSION(:),ALLOCATABLE :: V

	!*****LECTURE DES ARGUMENTS ENTREE EN LIGNE DE COMMANDE
	DO P=0,3
		CALL get_command_argument(p, arg)
		IF (LEN_TRIM(arg) == 0) exit 
		!WRITE (*,*) TRIM(arg)
		IF (p == 1) THEN
			read ( arg , '(i10)') DIM1
		ELSEIF (P == 2) then
			READ ( ARG, '(I10)') DIM2
		ELSEIF (P == 3) then
			READ ( ARG, '(I10)') F_COMPTEUR
		ENDIF
	END DO

	!********************POUR LA MATRICE PLEINE
	
	ALLOCATE (U(DIM2))
	ALLOCATE (A(DIM1*DIM2),STAT=IERR)
	ALLOCATE (V(DIM1))

	

	IF(IERR.NE.0) STOP 'ERREUR pour l allocation des matrices/vecteurs!'


	VALEURMAX=100000
	VALEURMIN=-100000
	! LES COEFFICIENTS DE A SONT ALEATOIRES
	
	DO J=1,DIM2
		DO I=1,DIM1
			CALL RANDOM_NUMBER(INTERMEDIAIRE)
			A(I+DIM1*(J-1))=INTERMEDIAIRE*(VALEURMAX-VALEURMIN)+VALEURMIN 
			V(I)=0
		END DO
		U(J)=J;
	END DO


	CALL GEMV_1D(A,U,V,DIM1,DIM2,F_COMPTEUR)
	
	! ON DESALLOUE TOUT CE QU'ON A ALLOUE
	DEALLOCATE(A)
	DEALLOCATE(U)
	DEALLOCATE(V)
	
	!END DO

	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------ESPACE SUBROUTINES------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	CONTAINS


	!SUBROUTINES MATRICE DENSE
	!-----------------------------------------------------------------------------
	! Fonction : GEMV_1D
	! Description :- calcul le produit matrice/vecteur dense et enregistre le temps d'execution et les parametre de la matrice dans un fichier
	! Paramètres : - A, la matrice dense sous forme vectorielle
	!              - u, le vecteur multiplie
	!              - v, le vecteur resultat
	! 			 - dim1, int dim2 les dimensions de la matrice
	! Retour: aucun
	!-----------------------------------------------------------------------------
	SUBROUTINE GEMV_1D(A,U,V,DIM1,DIM2,F_COMPTEUR)
	!DECLARATIONS PARAMETRES
	REAL *8:: T1,T2,TEMPS_MOY=0.0
	INTEGER, INTENT (IN) :: DIM1,DIM2,F_COMPTEUR
	INTEGER :: I,K,COMPTEUR=0
	TYP,DIMENSION(:), INTENT (IN) :: U
	TYP, DIMENSION (:), INTENT (IN) :: A
	TYP,DIMENSION(:), INTENT (OUT) :: V

	!CALCUL PRODUIT
	DO COMPTEUR=1,F_COMPTEUR
		!TOP CHRONO
		CALL CPU_TIME(T1)

		DO I=1,DIM1
			DO K=1,DIM2
			V(I)=V(I)+A(I+DIM1*(K-1))*U(K)
			END DO
		END DO
		!STOP CHRONO
		CALL CPU_TIME(T2)
		TEMPS_MOY=T2-T1+TEMPS_MOY
	END DO
	TEMPS_MOY=TEMPS_MOY/F_COMPTEUR
	WRITE(*,*) TEMPS_MOY


	END SUBROUTINE GEMV_1D

	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------END SUBROUTINES------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------
	!-------------------------------------------------------------------------------------------------------------------------------

END PROGRAM PROG_PRINC

!------------------------------------------------------------------------------
!MESSAGE D'ERREUR RETOURNER DANS LE TERMINAL
!a.out: malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
!Abandon
!--------------------------------------------------------------------------------------
